#!/usr/bin/python
# -*- coding: utf-8 -*-

import imaplib
import cPickle
import time
import os

settingsPath = "~/.mailToText"
updateInterval = 500
screensaverName = '.kss'
gmailUsername = 'jasonstextservice'
gmailPassword = 'gatechtextservice'

class Login:
	def __init__(self, username, password):
		self.username = username
		self.password = password


class MailboxInfo:
	def __init__(self, name, server, login, email):
		self.name = name
		self.server = server
		self.login = login
		self.email = email
		self.unseenMessages = []
		self.lastUpdate = 0

def loginToMailbox(server, login):
	mailbox = imaplib.IMAP4_SSL(server)
	ret, info = mailbox.login(login.username, login.password)
	if ret != 'OK':
		print("Problem logging into server with {0} user.".format(login.username))
		return None

	ret, info = mailbox.select(readonly=True)
	if ret != 'OK':
		print("Problem selecting the inbox.")
		return None

	return mailbox

def checkForNewMail(server, login):

	mailbox = loginToMailbox(server, login)
	if not mailbox:
		return []

	ret, info = mailbox.search(None, 'UNSEEN')
	if ret != 'OK':
		print("Problem checking mail.")
		return []

	mailbox.close()
	mailbox.logout()

	return [int(i) for i in info[0].split()]


def isScreensaverRunning():
	fout = os.popen('ps -A | grep {0}'.format(screensaverName))
	output = fout.read()
	fout.close()
	if output:
		return True
	else:
		return False


def clearSettingsFile():
	settingsFile = file(os.path.expanduser(settingsPath), 'wb')
	settingsFile.close()

def setupMailbox(name, server, username, password, email):

	settingsFile = file(os.path.expanduser(settingsPath), 'ab')
	pickler = cPickle.Pickler(settingsFile)
	
	login = Login(username, password)
	mailbox = MailboxInfo(name, server, login, email)

	pickler.dump(mailbox)

	settingsFile.close()


def getMailboxesFromFile():
	settingsFile = file(os.path.expanduser(settingsPath), 'rb')
	unpickler = cPickle.Unpickler(settingsFile)

	mailboxes = []

	while True:
		try:
			mailboxes.append(unpickler.load())
		except EOFError:
			break
			
	settingsFile.close()

	return mailboxes


def sendUpdate(mailboxInfo, new):

	import libgmail
	gmail = libgmail.GmailAccount(gmailUsername, gmailPassword)
	gmail.login()

	mailbox = loginToMailbox(mailboxInfo.server, mailboxInfo.login)
	if not mailbox:
		return

	messages = []

	for num in new:
		text = mailbox.fetch(num, "(BODY[TEXT])")[1][0][1]
		if text.find('Content-Type') != -1:
			line1 = text[0:text.find('\r\n')]
			start = text.find('Content-Transfer-Encoding')
			start = text.find('\r\n', start)+1
			text = text[start:text.find(line1, start)]
		text = text[0:1000]

		#strip out extra newlines in text...
		start = text.find('\r\n\r\n')
		while start > 0:
			text = text[:start]+text[start+2:]
			start = text.find('\r\n')
		
		header = mailbox.fetch(num, "(BODY[HEADER])")[1][0][1]
		start = header.find('From:')
		end = header.find('\r\n', start)
		sender = header[start:end]
		
		body = mailbox.fetch(num, "(BODY[])")[1][0][1]
		start = body.find("Subject:")
		end = body.find('\r\n', start)
		subject = body[start:end]

		messages.append({'text':text, 'subject':subject, 'from':sender})

	for mess in messages:
		toSend = "New email in {0} account\n{1}\n{2}\n{3}".format(mailboxInfo.name, mess['from'], mess['subject'], mess['text'])
		#print "sending message now", toSend
		gmsg = libgmail.GmailComposedMessage(mailboxInfo.email, "New Email in {0} account".format(mailboxInfo.name), toSend)
		if not gmail.sendMessage(gmsg):
			print("SMS Message failed")

def main():

	try:
		mailboxes = getMailboxesFromFile()
		#print mailboxes

		settingsFile = file(os.path.expanduser(settingsPath), 'wb')
		pickler = cPickle.Pickler(settingsFile)
		for mailbox in mailboxes:
			unseen = checkForNewMail(mailbox.server, mailbox.login)
			#print unseen
			#print mailbox.unseenMessages
			#wow that was convoluted, it is true if new is different from unseen
			new = [mail for mail in unseen if mail not in mailbox.unseenMessages]
			if new:
				#print("New Mail!! {0}".format(new))
				if isScreensaverRunning():
					sendUpdate(mailbox, new)
			mailbox.unseenMessages = unseen
			pickler.dump(mailbox)
	except:
		settingsFile.close()
		raise

if __name__=="__main__":
	main()